<?php
/** 
 * EGP Framework
 *
 * LICENSE
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 * @version    v1.0.0 Beta @ 2008-10-16
 */

!defined('EGP_LIB_DIR') && die('Access Deny!');

/**
 * Session 处理控制类
 *
 * @package    classes
 * @author     Akon(番茄红了) <aultoale@gmail.com>
 * @copyright  Copyright (c) 2008 (http://www.tblog.com.cn)
 * @license    http://www.gnu.org/licenses/gpl.html     GPL 3
 */
abstract class EGP_Session {

    /**
     * 标识 session 是否已启动
     *
     * @var boolean
     */
    protected static $_started = false;

    /**
     * session 命名空间名称
     *
     * @var string
     */
    protected static $_namespace = '_EGP';

    /**
     * session 配置选项
     *
     * @var array
     */
    protected static $_options = array(
        'name' => null,
        'path' => null,
        'seconds' => 86400,
        'domain' => null,
    );

    /**
     * 设定 session 选项
     *
     * @param  array  $options
     */
    public static function setOptions(array $options = array()) {
        foreach ($options as $k => $v)
            self::$_options[$k] = trim($v);
        $params = session_get_cookie_params();
        session_set_cookie_params(
            $params['lifetime'],
            $params['path'],
            self::$_options['domain'],
            $params['secure']
        );
    }

    /**
     * 启动 session
     *
     * @param  string  $namespace  session 命名空间
     */
    public static function start($namespace = null) {
        if (!self::$_started) {
            self::$_options['name'] && session_name(self::$_options['name']);
            self::$_options['path'] && session_save_path(EGP_Io::mkdir(self::$_options['path']));
            isset($_COOKIE[session_name()]) && session_id($_COOKIE[session_name()]);
            @session_start();
            session_cache_limiter('public, must-revalidate');
            self::$_started = true;
        }
        self::namespace($namespace);
    }

    /**
     * 将 session id 存储到 cookie 中
     *
     * @param  integer  $seconds  保存的秒数
     */
    public static function rememberMe($seconds = 86400) {
        $seconds = (integer) (null == $seconds ? self::$_options['seconds'] : $seconds);
        $seconds > 0 && setcookie(session_name(), session_id(), time() + $seconds);
    }

    /**
     * 清除 cookie 中的 session id
     *
     */
    public static function forgetMe() {
        setcookie(session_name(), session_id(), time() - 3600);
    }

    /**
     * 切换 session 命名空间
     *
     * @param  string  $namespace
     */
    public static function namespace($namespace) {
        if (!empty($namespace)) {
            if (preg_match('/[^A-Z_]/', $namespace))
                throw new EGP_Exception('session namespace 仅允许以下字符存在 [A-Z_]');
            self::$_namespace = $namespace;
        }
        return self::$_namespace;
    }

    /**
     * 取出命名空间下所有的 session 数据
     *
     * @return mixed
     */
    public static function fetchAll() {
        self::start();
        return isset($_SESSION[self::$_namespace]) ? $_SESSION[self::$_namespace] : null;
    }

    /**
     * 取出命名空间下指定名称的 session 数据
     *
     * @param  string  $name
     * @return mixed
     */
    public static function fetch($name) {
        self::start();
        return self::isRegistered($name) ? $_SESSION[self::$_namespace][$name] : null;
    }

    /**
     * 删除命名空间下所有的数据
     *
     * @param  string  $name
     */
    public static function clean() {
        self::start();
        unset($_SESSION[self::$_namespace]);
    }

    /**
     * 在命名空间下注册一个指定名称的数据
     *
     * @param  string  $name
     * @param  mixed   $name
     */
    public static function register($name, $value) {
        self::start();
        $_SESSION[self::$_namespace][$name] = $value;
    }

    /**
     * 在命名空间下删除一个指定名称的数据
     *
     * @param  string  $name
     */
    public static function unregister($name) {
        self::start();
        unset($_SESSION[self::$_namespace][$name]);
    }

    /**
     * 查询命名空间下是否存在指定名称的数据
     *
     * @param  string  $name
     * @return boolean
     */
    public static function isRegistered($name) {
        self::start();
        return isset($_SESSION[self::$_namespace][$name]);
    }

    /**
     * Sets user-level session storage functions
     *
     * @param EGP_Session_Handler_Interface $handler
     */
    public static function setSaveHandler(EGP_Session_Handler_Interface $handler)
    {
        session_set_save_handler(
            array(&$handler, 'open'),
            array(&$handler, 'close'),
            array(&$handler, 'read'),
            array(&$handler, 'write'),
            array(&$handler, 'destroy'),
            array(&$handler, 'gc')
        );
    }

}